
package todolist.logic.parser;

import todolist.entity.SortDirectionType;
import todolist.entity.TaskFieldType;
import todolist.personalization.ErrorMessages;
import todolist.personalization.TaskFieldCustomizer;
import todolist.util.Utils;

/**
 * Parser of Sort phrase, criteria followed by direction.
 * @author Ivan
 */
public class SortParser {
	
	private GenericParser _objGP;
	
	public SortParser() {
		_objGP = new GenericParser();
	}

	/**
	 * Tries to parse a String describing the Sort. Caller should check for Error in Parse Result.
	 * Return value never null, even if error.
	 * Error field of Parse Result is set to one of the ErrorMessages.
	 * Valid fields for sort are {Task Name, Date/Time, Priority, Status}.
	 */
	public SortParseResult parseSort(String pstrInput) {
		SortParseResult objResult = new SortParseResult();
		// no-match conditions
		objResult.setError(ErrorMessages.ERR_INVALID_SORT_FIELD); // assume invalid Sort Field first
		if (pstrInput == null)
			return objResult;
		pstrInput = pstrInput.trim();
		if (pstrInput.length() == 0)
			return objResult;
		// parse to try to find Task Field Type
		String strFront = pstrInput.split("\\s+")[0];
		pstrInput = Utils.discardNWordsFromString(pstrInput, 1);
		objResult.setTaskField(parseTaskField(strFront));
		if (objResult.getTaskField() == null)
			return objResult;
		// parse to try to find Sort Direction
		objResult.setError(ErrorMessages.ERR_INVALID_SORT_DIRECTION); // assume invalid Sort Direction first
		objResult.setSortDirection(parseSortDirection(pstrInput));
		if (objResult.getSortDirection() == null)
			return objResult; // if no match, invalid Sort Direction
		objResult.setError(null); // no error now
		return objResult; // all phrases do not match
	}
	
	// private methods

	/**
	 * Tries to parse a String containing Field to Sort.
	 * Task Field Type if found, or null otherwise, returned.
	 * Valid fields for sort are {Task Name, Date/Time, Priority, Status}.
	 */
	private TaskFieldType parseTaskField(String pstrInput) {
		if (_objGP.findMatch(TaskFieldCustomizer.getInstance().getInputFieldTaskName(), pstrInput) != null)
			return TaskFieldType.TASK_FIELD_TASKNAME;
		if (_objGP.findMatch(TaskFieldCustomizer.getInstance().getInputFieldDT(), pstrInput) != null)
			return TaskFieldType.TASK_FIELD_DT;
		if (_objGP.findMatch(TaskFieldCustomizer.getInstance().getInputFieldPriority(), pstrInput) != null)
			return TaskFieldType.TASK_FIELD_PRIORITY;
		if (_objGP.findMatch(TaskFieldCustomizer.getInstance().getInputFieldStatus(), pstrInput) != null)
			return TaskFieldType.TASK_FIELD_STATUS;
		return null; // if no match
	}

	/**
	 * Tries to parse a String containing Direction of Sort.
	 * Sort Direction Type if found, or null otherwise, returned.
	 */
	private SortDirectionType parseSortDirection(String pstrInput) {
		if (_objGP.findMatch(TaskFieldCustomizer.getInstance().getInputSortAscending(), pstrInput) != null) // ascending
			return SortDirectionType.SORT_ASC;
		if (_objGP.findMatch(TaskFieldCustomizer.getInstance().getInputSortDescending(), pstrInput) != null) // descending
			return SortDirectionType.SORT_DESC;
		return null; // if no match
	}
	
}
